package cn.itsource.basic.config;

import cn.itsource.basic.jwt.JwtUtils;
import cn.itsource.basic.jwt.LoginData;
import cn.itsource.basic.jwt.Payload;
import cn.itsource.basic.jwt.RsaUtils;
import cn.itsource.org.mapper.EmployeeMapper;
import cn.itsource.system.annotation.PreAuthorize;
import cn.itsource.user.domain.Logininfo;
import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.PublicKey;
import java.util.List;

@Component
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private EmployeeMapper employeeMapper;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        if(token != null){
            Logininfo info = null;
            //登录信息过期抛异常
            try {
                //获取登录对象信息    先生成公钥-----解密
                PublicKey publicKey = RsaUtils.getPublicKey(LoginInterceptor.class.getClassLoader().getResource("auth_rsa.pub").getFile());
                //通过公钥获取jwt对象
                Payload<LoginData> payload = JwtUtils.getInfoFromToken(token, publicKey, LoginData.class);
              //  final List<String> permissions = payload.getLoginData().getPermissions();

                //jwt对象获取login info对象
                info = payload.getLoginData().getLogininfo();
            } catch (ExpiredJwtException e) {
                //登录对象过期
                response.setContentType("application/json;charset=UTF-8");
                //返回信息放入下面{"success":false,"message":"noLogin"}
                response.getWriter().println("{\"success\":false,\"message\":\"Timeout\"}");
                return false;
            }
            //2.如果是管理员 - 校验权限
            if(info.getType()==1){
                return true;
            }
            //3.获取当前登录人的所有权限 - List<String> sns
            List<String> sns = employeeMapper.findSns(info.getId());
            //4.获取当前访问的接口上的自定义注解PreAuthorize，如果有这个注解，获取sn属性值
            HandlerMethod method = (HandlerMethod)handler;
            //获取当前访问的接口的名称
            //System.out.println(method.getMethod().getName());
            PreAuthorize preAuthorize = method.getMethodAnnotation(PreAuthorize.class);
            if(preAuthorize==null){
                return true;
            }
            //5.判断 - 如果包含 => 当前登录人有权限去访问当前接口 => 放行
            String sn = preAuthorize.sn();
            //有权限
            if(sns.contains(sn)){
                return true;
            }
            //6.判断 - 如果不包含 => 拦截，给axios的后置拦截器一个响应，打印出来
            //告诉浏览器，我等会要响应一个json数据，使用Utf-8进行编码 - 浏览器会自动转成对象
            response.setContentType("application/json;charset=UTF-8");
            //设置响应的数据
            response.getWriter().println("{\"success\":false,\"message\":\"noPermission\"}");
            //拦截了
            return false;
        }

        //token为空或者登录对象过期
        response.setContentType("application/json;charset=UTF-8");
        //返回信息放入下面{"success":false,"message":"noLogin"}
        response.getWriter().println("{\"success\":false,\"message\":\"noLogin\"}");
        return false;
    }
}
